using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using HslCommunication;
using HslCommunicationEx.VarMonitor;
using LambdaBuilder.Resolver;
using Catastrophe.AutoSulution.EDC;
using Catastrophe.Common.AttributeEx;
using Catastrophe.Common.Common;

namespace HslCommunicationEx.HslNet
{
	public abstract class BaseNetDeviceOpr : IBaseNetDeviceOpr
	{
		private DataTable _comDataDs;

		protected Dictionary<string, CommRecordInfo> DicOprTime;

		private Dictionary<string, Queue<CommRecordInfo>> _dicRecord;

		private Dictionary<string, Queue<CommRecordInfo>> _dicRecordTemp;

		public DataTable DataBind => this._comDataDs;

		public int RecordCapacity { get; set; } = 50;


		public bool IsAutoRecord { get; set; } = true;


		public Action<CommRecordInfo> CommRecordHandler { get; set; }

		public Action<string, Queue<CommRecordInfo>> CommRecordCompletedHandler { get; set; }

		public EndianModeEnum EndianMode { get; set; } = EndianModeEnum.Big;


		protected BaseNetDeviceOpr()
		{
			this._dicRecord = new Dictionary<string, Queue<CommRecordInfo>>();
			this._dicRecordTemp = new Dictionary<string, Queue<CommRecordInfo>>();
			this.DicOprTime = new Dictionary<string, CommRecordInfo>();
		}

		protected PropertyInfo GetFirtstOrDefaultProInfo<T>(Expression<Func<T, object>> exp)
		{
			List<string> buf = LambdaResolver.GetColumnNames(exp);
			if (buf.Count == 0)
			{
				throw new Exception("目标属性不存在！");
			}
			Type propertyType = this.GetPropertyType(typeof(T));
			return propertyType.GetProperties().FirstOrDefault((PropertyInfo x) => x.Name.Equals(buf[0]));
		}

		protected string GetFirtstOrDefaultName<T>(Expression<Func<T, object>> exp)
		{
			List<string> columnNames = LambdaResolver.GetColumnNames(exp);
			if (columnNames.Count == 0)
			{
				throw new Exception("目标属性不存在！");
			}
			return columnNames[0];
		}

		public virtual OperateResult ReadSingle<T>(Expression<Func<T, object>> exp, ushort len = 0)
		{
			string firtstOrDefaultName = this.GetFirtstOrDefaultName(exp);
			return this.ReadSingle<T>(firtstOrDefaultName, len);
		}

		public abstract OperateResult ReadSingle<T>(string filedName, ushort len = 0);

		public abstract Tuple<T, OperateResult> ReadEntityMuti<T>(T dstT) where T : class, new();

		public abstract OperateResult WriteEntitySingle<T>(string filedName, dynamic value, ushort attempTimes = 0, ushort attempInterval = 30) where T : class, new();

		public virtual OperateResult WriteEntitySingle(Type entityType, string filedName, dynamic value, ushort attempTimes = 0, ushort attempInterval = 30)
		{
			throw new NotImplementedException();
		}

		public virtual OperateResult WriteEntitySingle<T>(Expression<Func<T, object>> exp, dynamic value, ushort attempTimes = 0, ushort attempInterval = 30) where T : class, new()
		{
			List<string> columnNames = LambdaResolver.GetColumnNames(exp);
			if (columnNames.Count == 0)
			{
				throw new Exception("目标地址不存在！");
			}
			if (columnNames.Count > 1)
			{
				throw new Exception("目标地址只能一个！");
			}
			return WriteEntitySingle<T>(columnNames.First(), value, attempTimes);
		}

		public abstract OperateResult WriteEntityMuti<T>(T entity, Expression<Func<T, object>> exp, ushort attempTimes = 0, ushort attempInterval = 30) where T : class, new();

		protected dynamic GetValueDynamic(ReadQueue readQueue, byte[] values)
		{
			Type propertyType = this.GetPropertyType(readQueue.Property.PropertyType);
			string name = propertyType.Name;
			string text = name;
			if (text == "Array")
			{
				byte[] array = new byte[readQueue.ByteCount];
				Array.Copy(values, readQueue.StartIndex, array, 0, readQueue.ByteCount);
				return array;
			}
			return this.GetValueDynamic(readQueue.Property, values, readQueue.StartIndex, readQueue.BitIndex);
		}

		public virtual dynamic GetValueDynamic(DataTypeEnum dataType, byte[] values, int startIndex, int bitIndex)
		{
			return dataType switch
			{
				DataTypeEnum.Boolean => EnDeCode.ReturnGetbitValue(values[startIndex], bitIndex), 
				DataTypeEnum.Byte => values[startIndex], 
				DataTypeEnum.Int16 => EnDeCode.ConvertByteBufToT<short>(values, startIndex, this.EndianMode), 
				DataTypeEnum.UInt16 => EnDeCode.ConvertByteBufToT<ushort>(values, startIndex, this.EndianMode), 
				DataTypeEnum.Int32 => EnDeCode.ConvertByteBufToT<int>(values, startIndex, this.EndianMode), 
				DataTypeEnum.UInt32 => EnDeCode.ConvertByteBufToT<uint>(values, startIndex, this.EndianMode), 
				DataTypeEnum.Single => EnDeCode.ConvertByteBufToT<float>(values, startIndex, this.EndianMode), 
				DataTypeEnum.Int64 => EnDeCode.ConvertByteBufToT<long>(values, startIndex, this.EndianMode), 
				DataTypeEnum.Double => EnDeCode.ConvertByteBufToT<double>(values, startIndex, this.EndianMode), 
				DataTypeEnum.UInt64 => EnDeCode.ConvertByteBufToT<ulong>(values, startIndex, this.EndianMode), 
				DataTypeEnum.String => EnDeCode.ConvertByteBufToT<string>(values, startIndex, this.EndianMode), 
				_ => throw new Exception("不支持的数据类型" + dataType), 
			};
		}

		public virtual dynamic GetValueDynamic(PropertyInfo property, byte[] values, int startIndex, int bitIndex)
		{
			return this.GetValueDynamic(property.PropertyType, values, startIndex, bitIndex);
		}

		public virtual dynamic GetValueDynamic(Type dataType, byte[] values, int startIndex, int bitIndex)
		{
			Type propertyType = this.GetPropertyType(dataType);
			return propertyType.Name switch
			{
				"Boolean" => EnDeCode.ReturnGetbitValue(values[startIndex], bitIndex), 
				"Byte" => values[startIndex], 
				"Int16" => EnDeCode.ConvertByteBufToT<short>(values, startIndex, this.EndianMode), 
				"UInt16" => EnDeCode.ConvertByteBufToT<ushort>(values, startIndex, this.EndianMode), 
				"Int32" => EnDeCode.ConvertByteBufToT<int>(values, startIndex, this.EndianMode), 
				"UInt32" => EnDeCode.ConvertByteBufToT<uint>(values, startIndex, this.EndianMode), 
				"Int64" => EnDeCode.ConvertByteBufToT<long>(values, startIndex, this.EndianMode), 
				"UInt64" => EnDeCode.ConvertByteBufToT<ulong>(values, startIndex, this.EndianMode), 
				"Single" => EnDeCode.ConvertByteBufToT<float>(values, startIndex, this.EndianMode), 
				"Double" => EnDeCode.ConvertByteBufToT<double>(values, startIndex, this.EndianMode), 
				"String" => EnDeCode.ConvertByteBufToT<string>(values, startIndex, this.EndianMode), 
				_ => new Exception("不支持的数据类型" + dataType.Name), 
			};
		}

		public virtual int GetValue(PropertyInfo property, ComDataAttribute comData, ref dynamic value)
		{
			return this.GetValue(property.PropertyType, comData, ref value);
		}

		public virtual int GetValue(Type type, ComDataAttribute comData, ref dynamic value)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (comData == null)
			{
				throw new ArgumentNullException("comData");
			}
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			Type propertyType = this.GetPropertyType(type);
			switch (propertyType.Name.ToLower())
			{
			case "bool":
			case "boolean":
			case "system.boolean":
				value = Convert.ChangeType(value, typeof(bool));
				break;
			case "char":
			case "system.char":
				value = Convert.ChangeType(value, typeof(char));
				break;
			case "byte":
			case "system.byte":
				value = Convert.ChangeType(value, typeof(byte));
				break;
			case "int16":
			case "short":
			case "system.int16":
				value = Convert.ChangeType(value, typeof(short));
				break;
			case "uint16":
			case "ushort":
			case "system.uint16":
				value = Convert.ChangeType(value, typeof(ushort));
				break;
			case "int32":
			case "int":
			case "system.int32":
				value = Convert.ChangeType(value, typeof(int));
				break;
			case "uint32":
			case "uint":
			case "system.uint32":
				value = Convert.ChangeType(value, typeof(uint));
				break;
			case "int64":
			case "long":
			case "system.int64":
				value = Convert.ChangeType(value, typeof(long));
				break;
			case "uint64":
			case "ulong":
			case "system.uint64":
				value = Convert.ChangeType(value, typeof(ulong));
				break;
			case "single":
			case "float":
			case "system.single":
				value = Convert.ChangeType(value, typeof(float));
				break;
			case "double":
			case "system.double":
				value = Convert.ChangeType(value, typeof(double));
				break;
			case "string":
			case "system.string":
				value = Convert.ChangeType(value, typeof(string));
				break;
			default:
				throw new Exception("不支持的数据类型" + type.Name);
			}
			return this.GetByteCount(type, comData);
		}

		public virtual ushort GetByteCount(PropertyInfo propertyInfo, ComDataAttribute comData)
		{
			return this.GetByteCount(propertyInfo.PropertyType, comData);
		}

		public virtual ushort GetByteCount(Type type, ComDataAttribute comData)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (comData == null)
			{
				throw new ArgumentNullException("comData");
			}
			ushort num = 0;
			Type propertyType = this.GetPropertyType(type);
			switch (propertyType.Name)
			{
			case "Boolean":
				return 1;
			case "Char":
				return 1;
			case "Byte":
				return 1;
			case "Int16":
				return 2;
			case "UInt16":
				return 2;
			case "Int32":
				return 4;
			case "UInt32":
				return 4;
			case "Int64":
				return 8;
			case "UInt64":
				return 8;
			case "Single":
				return 4;
			case "Double":
				return 8;
			case "String":
			case "Array":
				return comData.ByteCount;
			default:
				throw new Exception("不支持的数据类型" + type.Name);
			}
		}

		public virtual void GetValue(DataTypeEnum dataType, ref dynamic value)
		{
			switch (dataType)
			{
			case DataTypeEnum.Boolean:
				value = Convert.ChangeType(value, typeof(bool));
				break;
			case DataTypeEnum.Byte:
				value = Convert.ChangeType(value, typeof(byte));
				break;
			case DataTypeEnum.Int16:
				value = Convert.ChangeType(value, typeof(short));
				break;
			case DataTypeEnum.UInt16:
				value = Convert.ChangeType(value, typeof(ushort));
				break;
			case DataTypeEnum.Int32:
				value = Convert.ChangeType(value, typeof(int));
				break;
			case DataTypeEnum.UInt32:
				value = Convert.ChangeType(value, typeof(uint));
				break;
			case DataTypeEnum.Single:
				value = Convert.ChangeType(value, typeof(float));
				break;
			case DataTypeEnum.Int64:
				value = Convert.ChangeType(value, typeof(long));
				break;
			case DataTypeEnum.Double:
				value = Convert.ChangeType(value, typeof(double));
				break;
			case DataTypeEnum.UInt64:
				value = Convert.ChangeType(value, typeof(ulong));
				break;
			case DataTypeEnum.String:
				value = Convert.ChangeType(value, typeof(string));
				break;
			default:
				throw new Exception("不支持的数据类型" + dataType);
			}
		}

		public virtual Tuple<OperateResult, ComDataAttribute> CheckReadAdr(PropertyInfo property)
		{
			ComDataAttribute comDataAttribute = Attribute.GetCustomAttribute(property ?? throw new InvalidOperationException(), typeof(ComDataAttribute)) as ComDataAttribute;
			if (comDataAttribute == null)
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "当前属性未标记ComDataAttribute"
				}, null);
			}
			if (comDataAttribute.Adr.Trim().Equals(string.Empty))
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult<byte[]>
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "地址为空！"
				}, null);
			}
			if (!comDataAttribute.OprType.HasFlag(OprTypeEnum.Read))
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "未标记Read！"
				}, null);
			}
			if (comDataAttribute.Ignore)
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "标记Ignore！"
				}, null);
			}
			return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
			{
				IsSuccess = true
			}, comDataAttribute);
		}

		public virtual Tuple<OperateResult, ComDataAttribute> CheckWriteAdr(PropertyInfo property)
		{
			ComDataAttribute comDataAttribute = Attribute.GetCustomAttribute(property ?? throw new InvalidOperationException(), typeof(ComDataAttribute)) as ComDataAttribute;
			if (comDataAttribute == null)
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "当前属性未标记ComDataAttribute"
				}, null);
			}
			if (comDataAttribute.Adr.Trim().Equals(string.Empty))
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult<byte[]>
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "地址为空！"
				}, null);
			}
			if (!comDataAttribute.OprType.HasFlag(OprTypeEnum.Write))
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "未标记Write！"
				}, null);
			}
			if (comDataAttribute.Ignore)
			{
				return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
				{
					IsSuccess = false,
					Message = "目标属性" + property.Name + "标记Ignore！"
				}, null);
			}
			return new Tuple<OperateResult, ComDataAttribute>(new OperateResult
			{
				IsSuccess = true
			}, comDataAttribute);
		}

		public virtual bool AndResult<T>(T entity, Expression<Func<T, object>> exp, IEnumerable<bool> joinBuf = null)
		{
			List<string> columnNames = LambdaResolver.GetColumnNames(exp);
			if (columnNames.Count == 0)
			{
				throw new Exception("目标地址不存在！");
			}
			Type propertyType = this.GetPropertyType(typeof(T));
			bool flag = true;
			List<PropertyInfo> list = new List<PropertyInfo>();
			foreach (string item in columnNames)
			{
				PropertyInfo property = propertyType.GetProperty(item);
				if (property != null && property.PropertyType == typeof(bool))
				{
					list.Add(property);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			foreach (PropertyInfo item2 in list)
			{
				bool flag2 = Convert.ToBoolean(item2.GetValue(entity));
				flag = flag && flag2;
			}
			if (joinBuf != null)
			{
				foreach (bool item3 in joinBuf)
				{
					flag = flag && item3;
				}
			}
			return flag;
		}

		public virtual bool OrResult<T>(T entity, Expression<Func<T, object>> exp, IEnumerable<bool> joinBuf = null)
		{
			List<string> columnNames = LambdaResolver.GetColumnNames(exp);
			if (columnNames.Count == 0)
			{
				throw new Exception("目标地址不存在！");
			}
			Type propertyType = this.GetPropertyType(typeof(T));
			bool flag = false;
			List<PropertyInfo> list = new List<PropertyInfo>();
			foreach (string item in columnNames)
			{
				PropertyInfo property = propertyType.GetProperty(item);
				if (property != null && property.PropertyType == typeof(bool))
				{
					list.Add(property);
				}
			}
			foreach (PropertyInfo item2 in list)
			{
				bool flag2 = Convert.ToBoolean(item2.GetValue(entity));
				flag = flag || flag2;
			}
			if (joinBuf != null)
			{
				foreach (bool item3 in joinBuf)
				{
					flag = flag || item3;
				}
			}
			return flag;
		}

		protected Type GetPropertyType(PropertyInfo property)
		{
			Type underlyingType = Nullable.GetUnderlyingType(property.PropertyType);
			return underlyingType ?? property.PropertyType;
		}

		protected Type GetPropertyType(Type type)
		{
			Type underlyingType = Nullable.GetUnderlyingType(type);
			return underlyingType ?? type;
		}

		public dynamic EndiaModeForamt(dynamic value, ComDataAttribute commAb, Type dstType, EndianModeEnum endiaMode)
		{
			object vlaue = value;
			if (dstType == null)
			{
				return vlaue;
			}
			if (commAb == null)
			{
				return vlaue;
			}
			if (!commAb.ByteReverse)
			{
				return vlaue;
			}
			string reverseFormat = commAb.ReverseFormat;
			if (!string.IsNullOrWhiteSpace(reverseFormat) && Valid.IsDecimal(reverseFormat))
			{
				List<char> charAry = reverseFormat.ToCharArray().Distinct().ToList();
				Func<byte[], bool> func = delegate(byte[] x)
				{
					if (x == null)
					{
						return false;
					}
					if (x.Length != charAry.Count)
					{
						return false;
					}
					return (x.Length == int.Parse(charAry.Max()!.ToString()) + 1) ? true : false;
				};
				byte[] array = null;
				byte[] array2 = value as byte[];
				array = ((array2 == null) ? ((byte[])EnDeCode.ConvertToByteBuf(value, endiaMode, commAb.ForceChangeHlByte)) : array2);
				if (!func(array))
				{
					return vlaue;
				}
				byte[] array3 = new byte[array.Length];
				for (int i = 0; i < charAry.Count; i++)
				{
					try
					{
						array3[i] = array[int.Parse(charAry[i].ToString())];
					}
					catch (Exception innerException)
					{
						throw new Exception("数据重组失败", innerException);
					}
				}
				return EnDeCode.ConvertByteBufToT(dstType, array3, 0, endiaMode);
			}
			dynamic propertyType = GetPropertyType(value.GetType());
			byte[] array4 = value as byte[];
			if (array4 != null)
			{
				return array4.Reverse();
			}
			if (propertyType.IsPrimitive)
			{
				EnDeCode.ConvertToDstType(ref vlaue, dstType, endiaMode);
				return vlaue;
			}
			return vlaue;
		}

		public abstract DataTable CreateDsSchema<T>() where T : class, new();

		public DataTable CreateDsSchema<T, TAb>() where TAb : ComDataAttribute
		{
			return this.CreateDsSchema<TAb>(typeof(T));
		}

		public DataTable CreateDsSchema<TAb>(Type entityType) where TAb : ComDataAttribute
		{
			if (this._comDataDs == null)
			{
				this._comDataDs = new DataTable();
				this._comDataDs.Columns.Add("Name");
				this._comDataDs.Columns.Add("Value");
				this._comDataDs.Columns.Add("ReadTimeStamp");
				this._comDataDs.Columns.Add("WriteTimeStamp");
				PropertyInfo[] properties = typeof(TAb).GetProperties();
				PropertyInfo[] array = properties;
				foreach (PropertyInfo propertyInfo in array)
				{
					this._comDataDs.Columns.Add(propertyInfo.Name);
				}
				var enumerable = from x in entityType.GetProperties()
					select new
					{
						Property = x,
						CommDataAb = (Attribute.GetCustomAttribute(x, typeof(TAb)) as TAb)
					} into x
					where x.CommDataAb != null
					select x;
				foreach (var item in enumerable)
				{
					if (!this.DicOprTime.ContainsKey(item.Property.Name))
					{
						this.DicOprTime.Add(item.Property.Name, null);
					}
					DataRow dataRow = this._comDataDs.NewRow();
					dataRow["Name"] = item.Property.Name;
					PropertyInfo[] array2 = properties;
					foreach (PropertyInfo propertyInfo2 in array2)
					{
						dataRow[propertyInfo2.Name] = propertyInfo2.GetValue(item.CommDataAb);
					}
					this._comDataDs.Rows.Add(dataRow);
				}
			}
			return this._comDataDs;
		}

		public void RecordRefreshManual<T, TAb>(T entity) where TAb : ComDataAttribute
		{
			if (this.IsAutoRecord || this._comDataDs == null)
			{
				return;
			}
			PropertyInfo[] properties = typeof(T).GetProperties();
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				DataRow dataRow = this._comDataDs.Select("Name='" + propertyInfo.Name + "'").FirstOrDefault();
				TAb val = Attribute.GetCustomAttribute(propertyInfo, typeof(TAb)) as TAb;
				if (val == null)
				{
					continue;
				}
				ComDataAttribute comDataAttribute = val;
				if (dataRow == null)
				{
					continue;
				}
				dataRow["Value"] = propertyInfo.GetValue(entity);
				if (this.DicOprTime.ContainsKey(propertyInfo.Name))
				{
					if (comDataAttribute.OprType == OprTypeEnum.Read)
					{
						dataRow["ReadTimeStamp"] = this.DicOprTime[propertyInfo.Name]?.ReadTimeStamp;
					}
					if (comDataAttribute.OprType == OprTypeEnum.Write)
					{
						dataRow["WriteTimeStamp"] = this.DicOprTime[propertyInfo.Name]?.WriteTimeStamp;
					}
				}
			}
		}

		protected void CommRecord<T>(PropertyInfo property, dynamic value, OprTypeEnum oprType) where T : ComDataAttribute
		{
			if (property == null)
			{
				throw new ArgumentNullException("property");
			}
			T val = Attribute.GetCustomAttribute(property, typeof(T)) as T;
			if (val != null)
			{
				CommRecord(val.IsRecord, property.Name, value, oprType);
			}
		}

		protected void CommRecord<T>(PropertyInfo property, T comAb, dynamic value, OprTypeEnum oprType) where T : ComDataAttribute
		{
			if (property == null)
			{
				throw new ArgumentNullException("property");
			}
			CommRecord(comAb.IsRecord, property.Name, value, oprType);
		}

		protected void CommRecord(bool isRecord, string name, dynamic value, OprTypeEnum oprType)
		{
			try
			{
				if (name == null)
				{
					throw new ArgumentNullException("name");
				}
				CommRecordInfo commRecordInfo = new CommRecordInfo
				{
					OprType = oprType,
					DstValue = value
				};
				string text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff");
				if (oprType == OprTypeEnum.Read)
				{
					commRecordInfo.ReadTimeStamp = text;
				}
				if (oprType == OprTypeEnum.Write)
				{
					commRecordInfo.WriteTimeStamp = text;
				}
				if (this.DicOprTime.ContainsKey(name))
				{
					this.DicOprTime[name] = commRecordInfo;
				}
				if (this.IsAutoRecord && this._comDataDs != null)
				{
					lock (this._comDataDs)
					{
						DataRow dataRow = this._comDataDs.Select("Name='" + name + "'").FirstOrDefault();
						if (dataRow != null)
						{
							dataRow["Value"] = (object)value;
							if (oprType == OprTypeEnum.Read)
							{
								dataRow["ReadTimeStamp"] = text;
							}
							if (oprType == OprTypeEnum.Write)
							{
								dataRow["WriteTimeStamp"] = text;
							}
						}
					}
				}
				if (isRecord)
				{
					RecordToQueue(name, text, value, oprType);
				}
				this.CommRecordHandler?.Invoke(commRecordInfo);
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private void RecordToQueue(string varName, string timeStamp, dynamic value, OprTypeEnum oprType)
		{
			if (!this._dicRecord.ContainsKey(varName))
			{
				this._dicRecord.Add(varName, new Queue<CommRecordInfo>());
			}
			if (!this._dicRecordTemp.ContainsKey(varName))
			{
				this._dicRecordTemp.Add(varName, new Queue<CommRecordInfo>());
			}
			this._dicRecord[varName].Enqueue(new CommRecordInfo
			{
				WriteTimeStamp = timeStamp,
				DstValue = value,
				OprType = oprType
			});
			this._dicRecordTemp[varName].Enqueue(new CommRecordInfo
			{
				WriteTimeStamp = timeStamp,
				DstValue = value,
				OprType = oprType
			});
			if (this._dicRecord[varName].Count > this.RecordCapacity)
			{
				this._dicRecord[varName].Dequeue();
			}
			if (this._dicRecordTemp[varName].Count >= this.RecordCapacity)
			{
				this.CommRecordCompletedHandler?.Invoke(varName, this._dicRecordTemp[varName]);
				this._dicRecordTemp[varName].Clear();
			}
		}

		public Queue<CommRecordInfo> GetRecordQueue(string name)
		{
			return this._dicRecord.ContainsKey(name) ? this._dicRecord[name] : new Queue<CommRecordInfo>();
		}
	}
}
